有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用Tic-Tac-Toe表示游戏状态的java

我目前正在为我的Data Structures课程做的作业的目标是创建一个量子Tic Tac Toe模型,该模型使用一个AI来赢得比赛

目前,我在寻找代表州的最有效方法时遇到了一些困难

当前结构概述:

抽象游戏

  • 拥有并管理AbstractPlayer(game.nextPlayer()通过int ID返回下一个玩家)
  • 在游戏开始时使用并初始化AbstractBoard
  • 具有游戏树(如果在初始化中调用,则完成,否则不完整)

AbstractBoard

  • 有一个状态、一个维度和一个父游戏
  • 是玩家和状态之间的中介(将状态从行集合转换为点表示)
  • 他是国家消费者

AbstractPlayer

  • 他是国家制片人
  • 有一个具体的评估策略来评估当前董事会

StateTransveralPool

  • 预计算“三态”的可能横截
  • 将它们存储在HashMap中,其中集合包含给定“3状态”的nextStates

状态

  • 包含3组--一组X-Moves、O-Moves和电路板
  • 集合中的每个整数都是一行。这些整数值可用于从StateCranversalPool获取下一行状态

因此,原则是 每行可以用二进制数000-111表示,其中0表示开放空间,1表示封闭空间

因此,对于不完整的TTT板:

From the Set<Integer> board perspective:
X_X  R1 might be: 101
OO_  R2 might be: 110
X_X  R3 might be: 101, where 1 is an open space, and 0 is a closed space

From the Set<Integer> xMoves perspective:
X_X  R1 might be: 101
OO_  R2 might be: 000
X_X  R3 might be: 101, where 1 is an X and 0 is not

From the Set<Integer> oMoves perspective:
X_X  R1 might be: 000
OO_  R2 might be: 110
X_X  R3 might be: 000, where 1 is an O and 0 is not

然后我们看到x{R1,R2,R3}&;o{R1,R2,R3}=>;电路板{R1、R2、R3}

问题是如何快速生成游戏树的下一个状态。如果玩家Max(x)有棋盘{R1,R2,R3},那么获取R1,R2和R3的下一行状态很简单

Set<Integer> R1nextStates = StateTransversalPool.get(R1); 

问题是我必须将这些状态中的每一个与R1和R2结合起来

除了Set之外,还有更好的数据结构可以使用吗?一般来说,有没有更有效的方法?我也发现了这一点<-&燃气轮机;国家调解很麻烦。有没有其他方法可以尝试

谢谢

这是我的ConcretePlayer类的代码。它可能有助于解释玩家如何使用StateProducer(可能需要成为StateFactory或StateBuilder)通过移动产生新的状态

public class ConcretePlayerGeneric extends AbstractPlayer {

 @Override
 public BinaryState makeMove() {
  // Given a move and the current state, produce a new state
  Point playerMove = super.strategy.evaluate(this);
  BinaryState currentState = super.getInGame().getBoard().getState();


  return StateProducer.getState(this, playerMove, currentState);
 }
}

编辑:我从普通的TTT开始,转到量子TTT。给定框架,它应该像创建几个新的具体类和调整一些东西一样简单


共 (2) 个答案

  1. # 1 楼答案

    每个正方形不应该只有三种可能的状态(,X,O)吗

    要么存储一个由3个状态方块组成的网格,要么存储2个移动列表。您不需要存储整个板,因为它是由移动定义的

    还有,你所说的:

    generating next states for the GameTree

    什么是游戏树?“下一个州”的例子是什么

  2. # 2 楼答案

    我的建议是:

    • 考虑表示单个正方形而不是行,其中+1 == O-1 == X0表示空正方形这允许您通过检查水平、垂直或对角线行的总和是否等于+3-3来检测结束状态
    • 其次,将该2D 3x3矩阵“展平”为单个数组,其中元素[0-2]表示第一行,元素[3-5]表示第二行,元素[6-8]表示第三行
    • 在给定棋盘当前状态的情况下,使用递归或迭代方法生成后续游戏状态

    编辑

    我觉得很无聊,所以决定写一些“玩具代码”来实现游戏板,包括确定它是否处于终端状态以及在下一步动作完成后生成一组板状态的方法。它应该推广到任何尺寸的板,尽管我还没有尝试过。享受

    样本输出

    $ java Board
    Creating board:
    
     -
     -
     -
    
    Initialising board:
    
    -OX
    O 
    XO-
    Terminal state: false
    
    
    Generating next move states:
    
    XOX
    O 
    XO-
    
    -OX
    OX-
    XO-
    
    -OX
    O-X
    XO-
    
    -OX
    O 
    XOX
    

    代码

    import java.util.List;
    import java.util.LinkedList;
    import java.util.Random;
    
    public class Board {
        private final int[] squares;
    
        public Board() {
        this.squares = new int[9];
        }
    
        protected Board(int[] squares) {
        this.squares = squares;
        }
    
        public void init() {
        Random rnd = new Random();
        int turn = 1; // 'O' always goes first.
    
            for (int i=0; i<squares.length; ++i) {
            double d = rnd.nextDouble();
    
            if (d < 0.75) {
            squares[i] = turn;
            turn = turn == 1 ? -1 : 1; // Flip to other player's turn.
            } else {
            squares[i] = 0; // Empty square.
            }
    
            if (isTerminalState()) {
            break;
            }
        }
        }
    
        public boolean isTerminalState() {
        boolean ret = false;
    
        boolean foundEmpty = false;
        int hSum = 0;
        int[] vSum = new int[3];
    
        for (int i=0; i<squares.length; ++i) {
            hSum += squares[i];
    
            if (isWinningRow(hSum)) {
            ret = true;
            break;
            } else if (i == 2 || i == 5) {
            hSum = 0;
            }
    
            int col = i % 3;
            vSum[col] += squares[i];
    
            if (isWinningRow(vSum[col])) {
            ret = true;
            break;
            }
    
            if (squares[i] == 0) {
            foundEmpty = true;
            }
        }
    
        if (!ret) {
            if (!foundEmpty) {
            ret = true;
            } else {
            int diag1 = 0;
            int diag2 = 0;
            int rowSz = (int)Math.sqrt(squares.length);
    
            for (int i=0; i<squares.length; ++i) {
                if (i % (rowSz + 1) == 0) {
                diag1 += squares[i];
    
                if (isWinningRow(diag1)) {
                    ret = true;
                    break;
                }
                }
    
                if (i > 0 && i % (rowSz - 1) == 0) {
                diag2 += squares[i];
    
                if (isWinningRow(diag2)) {
                    ret = true;
                    break;
                }
                }
            }
            }
        }
    
        return ret;
        }
    
        private boolean isWinningRow(int rowSum) {
        return rowSum == 3 || rowSum == -3;
        }
    
        public List<Board> getNextStates() {
        List<Board> ret = new LinkedList<Board>();
    
        int tmp = 0;
        for (int i=0; i<squares.length; ++i) {
            tmp += squares[i];
        }
    
        // Next turn is 'O' (i.e. +1) if the board sums to 0.
        // Otherwise it's 'X's turn.
        int turn = tmp == 0 ? 1 : -1;
    
        if (!isTerminalState()) {
            for (int i=0; i<squares.length; ++i) {
            if (squares[i] == 0) { // Empty square          
                int[] squaresA = new int[squares.length];
                System.arraycopy(squares, 0, squaresA, 0, squares.length);
                squaresA[i] = turn;
                ret.add(new Board(squaresA));
            }
            }
        }
    
        return ret;
        }
    
        public String toString() {
        StringBuilder sb = new StringBuilder();
    
        for (int i=0; i<squares.length; ++i) {
            if (squares[i] == 1) {
            sb.append('O');
            } else if (squares[i] == -1) {
            sb.append('X');
            } else {
            assert squares[i] == 0;
            sb.append('-');
            }
    
            if (i == 2 || i == 5) {
            sb.append('\n');
            }
        }
    
        return sb.toString();
        }
    
        public static void main(String[] args) {
        System.err.println("Creating board:\n");
        Board bd = new Board();
        System.err.println(bd);
    
        System.err.println("\nInitialising board:\n");
        bd.init();
        System.err.println(bd);
        System.err.println("Terminal state: " + bd.isTerminalState() + '\n');
    
        System.err.println("\nGenerating next move states:\n");
        List<Board> nextStates = bd.getNextStates();
    
        for (Board bd1 : nextStates) {
            System.err.println(bd1.toString() + '\n');
        }
        }
    }